﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace CellarDoor.Gui.Elements
{
    public class UiScrollPane : UiElement
    {
        private UiScrollBar scrollH;
        /// <summary>
        /// The horizontal scrollbar element
        /// </summary>
        public UiScrollBar ScrollH
        {
            get { return scrollH; }
        }

        private UiScrollBar scrollV;
        /// <summary>
        /// The vertical scrollbar element
        /// </summary>
        public UiScrollBar ScrollV
        {
            get { return scrollV; }
        }

        private UiPanel container;
        /// <summary>
        /// The inner container with child elements
        /// </summary>
        public UiPanel Container
        {
            get { return container; }
        }

        /// <summary>
        /// Creates a new scroll pane
        /// </summary>
        /// <param name="manager"></param>
        public UiScrollPane()
            : base()
        {
            Initialize();
        }

        /// <summary>
        /// Creates a new scroll pane
        /// </summary>
        /// <param name="parent"></param>
        public UiScrollPane(UiElement parent)
            : base(parent)
        {
            Initialize();
        }

        private void Initialize()
        {
            container = new UiPanel();
            container.ElementName = null;
            this.Elements.Add(container);

            scrollH = new UiScrollBar();
            scrollH.BarStyle = UiOrientation.Horizontal;
            scrollH.Height = 25;
            scrollH.Dock = UiDockStyles.Bottom;
            this.Elements.Add(scrollH);

            scrollV = new UiScrollBar();
            scrollV.BarStyle = UiOrientation.Vertical;
            scrollV.Width = 25;
            scrollV.Dock = UiDockStyles.Right;
            this.Elements.Add(scrollV);
        }

        public override UiElement AddElement(UiElement element)
        {
            return container.AddElement(element);
        }

        public override void Clear()
        {
            Elements.Clear();
            Elements.Add(container);
            Elements.Add(scrollH);
            Elements.Add(scrollV);
        }

        protected override void DrawChildren(Vector4 color)
        {
            base.DrawChildren(color);

            float dx = container.Width;
            float dy = container.Height;

            float offX = Padding.Left;
            float offY = Padding.Top;

            float iw1 = InnerWidth1;
            float ih1 = InnerHeight1;

            if (scrollV.Visible != container.Width < iw1)
            {
                scrollV.Visible = !scrollV.Visible;
                InvalidateLayout();
            }
            if (scrollH.Visible != container.Height < ih1)
            {
                scrollH.Visible = !scrollH.Visible;
                InvalidateLayout();
            }

            float iw = InnerWidth;
            float ih = InnerHeight;

            if (dx > iw)
            {
                offX = (dx - iw) * scrollH.Value;
            }

            if (dy > ih)
            {
                offY = (dy - ih) * scrollV.Value;
            }

            container.Location = new Vector2(Padding.Left, Padding.Top) - new Vector2(offX, offY);
            container.ScissorEnable = true;
            container.Scissor = InnerArea;
        }

        private int InnerX
        {
            get { return (int)(Layout.Area.X + Padding.Left); }
        }

        private int InnerY
        {
            get { return (int)(Layout.Area.Y + Padding.Top); }
        }

        private int InnerWidth1
        {
            get { return (int)(Width - Padding.Left - Padding.Right); }
        }

        private int InnerWidth
        {
            get { return (int)(InnerWidth1 - (scrollV.Visible ? scrollV.Width : 0)); }
        }

        private int InnerHeight1
        {
            get { return (int)(Height - Padding.Top - Padding.Bottom); }
        }

        private int InnerHeight
        {
            get { return (int)(InnerHeight1 - (scrollH.Visible ? scrollH.Height : 0)); }
        }

        private Rectangle InnerArea
        {
            get 
            {
                return new Rectangle(InnerX, InnerY, InnerWidth, InnerHeight);
            }
        }
    }
}
